home *** CD-ROM | disk | FTP | other *** search
- /*
- * TOOLBAR.C -- Tool Bar control
- */
-
- #include <windows.h>
- #include "toolbar.h"
-
- #define MAXTOOLBARBM 255 /* Maximum bitmaps. */
- #define TBNOSELECT MAXTOOLBARBM + 1 /* No selection made. */
-
- static char szBorderProp[] = "BORDER"; /* Border width property. */
- static char szSizeProp[] = "SIZE"; /* Tool bar size property. */
- static char szUnitProp[] = "UNIT"; /* Atomic size property. */
- static char szToolBitProp[] = "TOOLBITS"; /* Array of RECTs handle. */
- static char szNumBitmaps[] = "NUMBMS"; /* # of bitmaps received. */
-
- static int HitTest( int x, int y, LPRECT lpRects, int nNumBitmaps )
- {
-
- /* Examine the array of bitmap RECTs to see if x,y is contained */
- /* in one. */
-
- int nBitmap;
- POINT point;
-
- point.x = x;
- point.y = y;
-
- /* Iterate through the array of RECTS and see if the point (x,y) */
- /* is contained in any of them. */
-
- for (nBitmap = 0; nBitmap < nNumBitmaps; nBitmap++)
- {
- if (PtInRect( lpRects+nBitmap, point ) )
- return nBitmap;
- }
-
- return TBNOSELECT;
-
- }
-
-
- static void SetToolBarState( HWND hwnd, int iState )
- {
-
- /* Change the state of the toolbar and invalide the client area */
- /* so that a WM_PAINT message is generated. */
-
- if ( GET_TBSTATE != iState )
- InvalidateRect( hwnd, NULL, FALSE );
- SET_TBSTATE( iState );
-
- }
-
- static void PaintToolBar( HWND hwnd, HDC hdc )
- {
-
- /* Display the tool bar on the screen by sending a series of */
- /* TB_TOOLBAR messages to the parent window and constructing */
- /* the tool bar accordingly. The tool bar is finished and ready */
- /* to be displayed when the parent stops responding. */
-
- int nPos, x, y;
- int nHoriz;
- int nVert;
- HDC hdcMem, hdcBitmap;
- HBITMAP hBitmap;
- HBITMAP hToolBarBitmap;
- RECT clientRect;
- int nBorder;
- int nXUnit, nYUnit;
- HANDLE hToolBarBM;
- int nNumBitmaps;
- int nMaxPos;
- LPRECT lpRects;
- BITMAP bm;
- RECT bmRect;
-
- /* Get parameters passed when the tool bar was created. These */
- /* were saved in the property lists. */
-
- nBorder = GetProp( hwnd, szBorderProp );
- nXUnit = GetProp( hwnd, szUnitProp ) >> 8;
- nYUnit = GetProp( hwnd, szUnitProp ) & 0x00FF;
- nHoriz = GetProp( hwnd, szSizeProp ) >> 8;
- nVert = GetProp( hwnd, szSizeProp ) & 0x00FF;
-
- /* Get array of RECTs (cells). The handle is a a property, and */
- /* get the pointer to the list. */
-
- hToolBarBM = GetProp( hwnd, szToolBitProp );
- lpRects = (LPRECT) GlobalLock( hToolBarBM );
-
- GetClientRect( hwnd, &clientRect );
-
- /* Set up a bitmap for drawing the tool bar */
-
- hdcMem = CreateCompatibleDC( hdc );
-
- hToolBarBitmap = CreateCompatibleBitmap( hdc,
- clientRect.right,
- clientRect.bottom );
-
- SelectObject( hdcMem, hToolBarBitmap );
- SetMapMode( hdcMem, GetMapMode( hdc ) );
-
- /* Fill in background colors, first the gray border. */
-
- FillRect( hdcMem, &clientRect, GetStockObject( LTGRAY_BRUSH ) );
-
- /* Then the black inner area. */
-
- InflateRect( &clientRect, -nBorder, -nBorder );
- FillRect( hdcMem, &clientRect, GetStockObject( BLACK_BRUSH ) );
- InflateRect( &clientRect, nBorder, nBorder );
-
- hdcBitmap = CreateCompatibleDC( hdc );
-
- nMaxPos = nHoriz * nVert; /* Compute max grid positions. */
- nNumBitmaps = 0;
-
- /* Iterate through all possible cell positions. */
-
- for ( nPos = 0; nPos < nMaxPos; nPos++ )
- {
- SET_TBBITMAP( hwnd, 0 );
-
- /* Get a bitmap from the parent by sending a message. The */
- /* high-order word of the LONG parameter is the bitmap number */
- /* and the low-order word is the 1 if it is selected, and 0 */
- /* otherwise. */
-
- SendMessage( GetParent(hwnd),TB_TOOLBAR,hwnd,
- MAKELONG( nNumBitmaps,
- ((nNumBitmaps == GET_TBSTATE) ? TRUE : FALSE)));
-
- hBitmap = GET_TBBITMAP;
- if (hBitmap)
- {
-
- /* Use HitTest to see if the cell position is occupied. */
-
- do
- {
- x = ((nPos * nXUnit) % (nHoriz * nXUnit)) +
- nBorder + ((nPos % nHoriz) + 1);
- y = ((nPos / nHoriz) * nYUnit) + nBorder +
- ((nPos / nHoriz) + 1);
- } while ( (HitTest( x, y, lpRects, nNumBitmaps ) != TBNOSELECT)
- && (nPos++ < nMaxPos) );
-
- if (nPos == nMaxPos)
- break;
-
- /* Set up bitmap dimensions for the array of RECTs, and */
- /* add it to the list of RECTs (cells). */
-
- GetObject( hBitmap, sizeof(BITMAP), (LPSTR) &bm );
- bmRect.left = x;
- bmRect.top = y;
- bmRect.right = x + bm.bmWidth + 1;
- bmRect.bottom = y + bm.bmHeight + 1;
-
- lpRects[ nNumBitmaps++ ] = bmRect;
-
- SelectObject( hdcBitmap, hBitmap );
- SetMapMode( hdcBitmap, GetMapMode( hdc ) );
-
- /* Copy position bitmap to tool bar bitmap. */
-
- BitBlt( hdcMem, x, y, bm.bmWidth, bm.bmHeight,
- hdcBitmap, 0, 0, SRCCOPY );
-
- }
- if ( nNumBitmaps > MAXTOOLBARBM )
- break;
- }
-
- DeleteDC( hdcBitmap );
-
- /* Copy the tool bar bitmap to screen. */
-
- BitBlt( hdc, 0, 0, clientRect.right, clientRect.bottom,
- hdcMem, 0, 0, SRCCOPY );
-
- DeleteDC( hdcMem );
- DeleteObject( hToolBarBitmap );
-
- SetProp( hwnd, szNumBitmaps, nNumBitmaps );
- GlobalUnlock( hToolBarBM );
-
- }
-
- LONG FAR PASCAL ToolBarWndFn(HWND hwnd, WORD message,
- WORD wParam, LONG lParam)
- {
-
- /* This is the main window procedure of the tool bar. Its main */
- /* job is to display the tool bar on the screen and detect mouse */
- /* mouse clicks within it. If the tool bar state changes, the */
- /* the parent is notified and the tool bar is updated. */
-
- int x, y;
- PAINTSTRUCT ps;
- HDC hdc;
- HANDLE hToolBarBM;
- int nNumBitmaps;
- LPRECT lpRects;
- int nResult;
-
- switch (message)
- {
- case WM_CREATE:
-
- SET_TBSTATE( TBNOSELECT ); /* Initially, no selection */
-
- /* Activate ourselves so we appear active. */
-
- SendMessage( hwnd, WM_NCACTIVATE, 1, 0L );
-
- break;
-
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
-
- BringWindowToTop( hwnd );
-
- /* Get the array of RECTs and the size of the array. */
-
- hToolBarBM = GetProp( hwnd, szToolBitProp );
- lpRects = (LPRECT) GlobalLock( hToolBarBM );
- nNumBitmaps = GetProp( hwnd, szNumBitmaps );
-
- x = LOWORD(lParam);
- y = HIWORD(lParam);
-
- nResult = HitTest( x, y, lpRects, nNumBitmaps );
-
- /* If a selection is made, change state and send a message */
- /* to our parent. */
-
- if (nResult != TBNOSELECT)
- {
- SetToolBarState( hwnd, nResult );
- SendMessage( GetParent(hwnd), TB_CLICKED, hwnd,
- MAKELONG( nResult, 0 ) );
- }
-
- GlobalUnlock( hToolBarBM );
- break;
-
- case WM_ERASEBKGND:
-
- /* Swallow the message; the background need not be painted */
-
- return TRUE;
-
- case WM_PAINT:
-
- hdc = BeginPaint( hwnd, &ps );
-
- PaintToolBar( hwnd, hdc );
-
- EndPaint( hwnd , &ps );
-
- return TRUE;
-
- case TB_SETSELECT:
-
- if (wParam)
- SetToolBarState( hwnd, LOWORD(lParam) );
- else
- SetToolBarState( hwnd, TBNOSELECT );
-
- return TRUE;
-
- case TB_GETSELECT:
-
- return GET_TBSTATE;
-
- case WM_NCACTIVATE:
-
- wParam = TRUE; /* Enforce activation. */
-
- break;
-
- case WM_DESTROY:
-
- RemoveProp( hwnd, szBorderProp );
- RemoveProp( hwnd, szUnitProp );
- RemoveProp( hwnd, szSizeProp );
-
- hToolBarBM = GetProp( hwnd, szToolBitProp );
- GlobalFree( hToolBarBM );
-
- RemoveProp( hwnd, szToolBitProp );
- RemoveProp( hwnd, szNumBitmaps );
-
- break;
-
- default:
-
- break;
-
- }
-
- return DefWindowProc (hwnd, message, wParam, lParam);
- }
-
-
- HWND FAR PASCAL CreateToolBar( HANDLE hInstance, HWND hWndApp,
- DWORD dwStyle, int x, int y,
- int nXUnit, int nYUnit,
- int nHoriz, int nVert,
- int nBorder, LPSTR lpTitle )
- {
-
- /* This function creates a new tool bar. It saves most of its */
- /* information in the form of window properties so that the window */
- /* procedure can retrieve them when necessary. */
-
- int nHeight, nWidth;
- HWND hToolBarWnd;
- HANDLE hToolBarBM;
-
- nWidth = (nHoriz * nXUnit) + (nBorder * 2) + (nHoriz+1) +
- (2 * GetSystemMetrics( SM_CXBORDER ) );
- nHeight = (nVert * nYUnit) + (nBorder * 2) + (nVert+1) +
- GetSystemMetrics( SM_CYCAPTION ) +
- GetSystemMetrics( SM_CYBORDER );
-
- hToolBarWnd = CreateWindow( "ToolBar", lpTitle,
- dwStyle | WS_CHILD | WS_CLIPSIBLINGS,
- x, y,
- nWidth,
- nHeight,
- hWndApp, NULL,
- hInstance, NULL );
-
- SetProp( hToolBarWnd, szBorderProp, nBorder );
- SetProp( hToolBarWnd, szUnitProp, (nXUnit << 8) + nYUnit );
- SetProp( hToolBarWnd, szSizeProp, (nHoriz << 8) + nVert );
-
- /* Allocate memory for the maximum number of bitmaps. This is */
- /* the list of cells that is used to determine the position of */
- /* the bitmaps within the client area of the tool bar. */
-
- hToolBarBM = GlobalAlloc( GMEM_SHARE | GMEM_ZEROINIT,
- sizeof(RECT) * MAXTOOLBARBM );
- if ( hToolBarBM )
- SetProp( hToolBarWnd, szToolBitProp, hToolBarBM );
- SetProp( hToolBarWnd, szNumBitmaps, 0 );
-
- return hToolBarWnd;
-
- }